import os
import fdt


def scan_dts_files(path):
    dts_files = []
    for root, dirs, files in os.walk(path):
        try:
            for file in files:
                if file.endswith(".dts"):
                    dts_files.append(file)
        except PermissionError:
            print(f"Permission denied for file: {file}")
    return dts_files

def change_ext_in_str(file_path, new_ext):
    base = os.path.splitext(file_path)[0]
    return base + '_dtb' + new_ext

def get_dtb(filename):
    with open(filename, 'r') as f:
        dts_text = f.read()
        dt = fdt.parse_dts(dts_text)
        dtb = dt.to_dtb(version=17)
    return dtb

def dts_to_c(input_file, output_c, output_h):
    dtb = get_dtb(input_file)
    hex_array = [f"0x{byte:02x}" for byte in dtb]
    hex_lines = [", ".join(hex_array[i:i+16]) for i in range(0, len(hex_array), 16)]
    c_code = f'// Auto-generated from {os.path.splitext(input_file)[0]}\n'
    c_code += f'#include \"{output_h}\"\n'
    c_code += "static const unsigned char dtb_blob[] __attribute__((aligned(64))) = {\n    " + ",\n    ".join(hex_lines) + "\n};\n"
    c_code += '''const void * dtb_get_blob_data(void)
{
    return dtb_blob;
}

unsigned int dtb_get_blob_size(void)
{
    return sizeof(dtb_blob);
}
'''
    with open(output_c, "w") as f:
        f.write(c_code)

def generate_header(input_file, output_h):
    c_code = f'// Auto-generated from {input_file}\n'
    c_code += '#ifndef __DTB_BLOB_DATA_H__\n'
    c_code += '#define __DTB_BLOB_DATA_H__\n'
    c_code += 'const void * dtb_get_blob_data(void);\n'
    c_code += 'unsigned int dtb_get_blob_size(void);\n'
    c_code += '#endif /* __DTB_BLOB_DATA_H__ */'
    with open(output_h, "w") as f:
        f.write(c_code)
def main():
    scan_path = os.path.join(os.getcwd(), "dts")
    output_path = os.path.join(os.getcwd(), "output")
    if not os.path.exists(output_path):
        os.mkdir(output_path)
    dts_files = scan_dts_files(scan_path)
    for f in dts_files:
        output_dir = os.path.join(output_path, os.path.splitext(f)[0])
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)
        file = os.path.join(scan_path, f)
        output_c = 'dtb_blob_data.c'
        output_h = 'dtb_blob_data.h'
        output_c_path = os.path.join(output_path, output_dir, output_c)
        output_h_path = os.path.join(output_path, output_dir, output_h)
        dts_to_c(file, output_c_path, output_h)
        generate_header(f, output_h_path)
        print(f'Generate dtb {output_dir}')

if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(e)
        input()